package xin.marcher.module.diplomacy.api.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import xin.marcher.module.common.constants.diplomacy.AbstractRedisKeyConstants;
import xin.marcher.module.common.core.JsonResult;
import xin.marcher.module.common.exception.ProductErrorCodeEnum;
import xin.marcher.module.common.utils.JsonUtil;
import xin.marcher.module.common.utils.ParamCheckUtil;
import xin.marcher.module.diplomacy.api.ProductPurchaseApi;
import xin.marcher.module.diplomacy.domain.dto.ProductPurchaseCollectDTO;
import xin.marcher.module.diplomacy.domain.dto.ProductPurchaseRelationDTO;
import xin.marcher.module.diplomacy.domain.entity.ProductDetailDO;
import xin.marcher.module.diplomacy.domain.query.ProductPurchaseQuery;
import xin.marcher.module.diplomacy.domain.query.ProductPurchaseRelationQuery;
import xin.marcher.module.diplomacy.manager.custom.cache.SkuSellerCache;

import javax.annotation.Resource;
import java.util.*;

import static xin.marcher.module.common.constants.diplomacy.BaseConstants.PAGE_NO_1;
import static xin.marcher.module.common.constants.diplomacy.BaseConstants.PAGE_SIZE_1000;

/**
 * 商品可采服务
 */
@Slf4j
@DubboService(version = "1.0.0", interfaceClass = ProductPurchaseApi.class, retries = 0)
public class ProductPurchaseApiImpl implements ProductPurchaseApi {

    @Resource
    private SkuSellerCache skuSellerCache;

    /**
     * 分页查询可采商品
     *
     * @param productPurchaseQuery
     * @return
     */
    @Override
    public JsonResult<ProductPurchaseCollectDTO> getPurchaseSkuByPage(ProductPurchaseQuery productPurchaseQuery) {
        checkPurchaseSkuByPageParams(productPurchaseQuery);

        int pageNo = PAGE_NO_1;
        int pageSize = PAGE_SIZE_1000;
        if (Objects.nonNull(productPurchaseQuery.getPageNo())) {
            pageNo = productPurchaseQuery.getPageNo();
        }
        if (Objects.nonNull(productPurchaseQuery.getPageSize())) {
            pageSize = productPurchaseQuery.getPageSize();
        }
        int offset = (pageNo - 1) * pageSize;

        String redisKey = AbstractRedisKeyConstants.getSellerTypePurchaseSkuZsetKey(productPurchaseQuery.getSellerGroupId());
        Optional<List<String>> optional = skuSellerCache.listRedisSortedSetData(productPurchaseQuery.getSellerGroupId(),
                offset, pageSize, AbstractRedisKeyConstants::getSellerTypePurchaseSkuZsetKey);
        if (!optional.isPresent()) {
            return JsonResult.buildError(ProductErrorCodeEnum.NO_RESULT_ERROR);
        }

        boolean nextPage = false;
        Long count = skuSellerCache.zcard(redisKey);
        if (count.intValue() > (offset + pageSize)) {
            nextPage = true;
        }

        ProductPurchaseCollectDTO productPurchaseCollectDTO = new ProductPurchaseCollectDTO();
        productPurchaseCollectDTO.setSkuIdList(optional.get());
        productPurchaseCollectDTO.setNextPage(nextPage);
        productPurchaseCollectDTO.setTotal(count);
        return JsonResult.buildSuccess(productPurchaseCollectDTO);
    }

    /**
     * 根据卖家ID和商品编码判断商品是否可采
     *
     * @param productPurchaseRelationQuery
     * @return
     */
    @Override
    public JsonResult<ProductPurchaseRelationDTO> checkPurchaseSku(ProductPurchaseRelationQuery productPurchaseRelationQuery) {
        // 参数校验
        checkPurchaseSkuParams(productPurchaseRelationQuery);

        List<Long> sellerIdList = productPurchaseRelationQuery.getSellerGroupIdList();

        // 获取卖家可采商品集合
        Optional<Map<Long, List<String>>> optional = skuSellerCache.queryRedisSortedSetDataMap(sellerIdList,
                AbstractRedisKeyConstants::getSellerTypePurchaseSkuZsetKey);

        if (!optional.isPresent()) {
            return JsonResult.buildSuccess();
        }

        // 构建可采商品和卖家关系,以及不可采商品列表
        ProductPurchaseRelationDTO productPurchaseRelationDTO = buildProductPurchaseRelation(optional.get(),
                productPurchaseRelationQuery.getProductIdList());

        return JsonResult.buildSuccess(productPurchaseRelationDTO);
    }

    /**
     * 构建可采商品和卖家关系,以及不可采商品列表
     *
     * @param skuIdMap
     * @param productIdList
     * @return
     */
    private ProductPurchaseRelationDTO buildProductPurchaseRelation(Map<Long, List<String>> skuIdMap, Set<String> productIdList) {

        List<String> notPurchaseProductIds = new ArrayList<>(productIdList.size());
        notPurchaseProductIds.addAll(productIdList);

        Map<Long, List<String>> sellerPurchaseProductIds = new HashMap<>(skuIdMap.size());
        for (Map.Entry<Long, List<String>> entry : skuIdMap.entrySet()) {
            List<String> purchaseProductIds = entry.getValue();
            List<String> purchaseList = new ArrayList<>(purchaseProductIds.size());
            for (String sku : purchaseProductIds) {
                ProductDetailDO productDetailDO = JsonUtil.json2Object(sku, ProductDetailDO.class);
                if (productIdList.contains(productDetailDO.getSkuId())) {
                    purchaseList.add(sku);
                    notPurchaseProductIds.remove(productDetailDO.getSkuId());
                }
            }
            // 当前卖家可采商品
            sellerPurchaseProductIds.put(entry.getKey(), purchaseList);
        }

        return new ProductPurchaseRelationDTO(sellerPurchaseProductIds, notPurchaseProductIds);

    }

    /**
     * 参数校验
     *
     * @param productPurchaseQuery
     */
    private void checkPurchaseSkuByPageParams(ProductPurchaseQuery productPurchaseQuery) {
        ParamCheckUtil.checkObjectNonNull(productPurchaseQuery);
        ParamCheckUtil.checkLongNonEmpty(productPurchaseQuery.getSellerGroupId());
    }

    /**
     * 参数校验
     *
     * @param productPurchaseRelationQuery
     */
    private void checkPurchaseSkuParams(ProductPurchaseRelationQuery productPurchaseRelationQuery) {
        ParamCheckUtil.checkObjectNonNull(productPurchaseRelationQuery);
        ParamCheckUtil.checkCollectionNonEmpty(productPurchaseRelationQuery.getProductIdList());
        ParamCheckUtil.checkCollectionNonEmpty(productPurchaseRelationQuery.getSellerGroupIdList());
    }
}
